package com.yonyou.crm.base.attr.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.yonyou.crm.base.attr.entity.AttrBVO;
import com.yonyou.crm.common.biz.service.BaseBizServiceImpl;
import com.yonyou.crm.common.exception.CrmBusinessException;
import com.yonyou.crm.common.rowstate.constant.RowStateConstant;
import com.yonyou.iuap.context.InvocationInfoProxy;

@Service
public class AttrBBizServiceImpl extends BaseBizServiceImpl<AttrBVO> {

	/**
	 * 批量新增属性值
	 * @param attrId
	 * @param voList
	 */
	public void batchInsertVO(Long attrId, List<AttrBVO> voList) {
		
		if (voList == null || voList.size() == 0) {
			return;
		}
		
		Long userId = new Long(InvocationInfoProxy.getParameter("id"));
		Long tenantId = new Long(InvocationInfoProxy.getTenantid());
		Date date = new Date();
		
		for (AttrBVO vo : voList) {
			vo.setAttrId(attrId);
			vo.setTenantId(tenantId);
			vo.setSysCreatedTime(date);
			vo.setSysCreatedUserId(userId);
			vo.setSysModifiedTime(date);
			vo.setSysModifiedUserId(userId);
			vo.setEnableTime(date);
			vo.setEnableUserId(userId);
		}

		dao.saveSql(AttrBVO.class, "batchInsertAttrB", voList);
	}
	
	/**
	 * 批量修改
	 * @param attrId
	 * @param voList
	 */
	public void batchUpdateVO(Long attrId, List<AttrBVO> voList) {
		
		List<AttrBVO> addList = new ArrayList<AttrBVO>();
		List<AttrBVO> updateList = new ArrayList<AttrBVO>();
		List<String> deleteList = new ArrayList<String>();
		List<String> existValueList = new ArrayList<String>();
		
		for (AttrBVO vo : voList) {
			
			switch (vo.getEditState()) {
			case RowStateConstant.ADD:
				addList.add(vo);
				validValue(attrId, vo, existValueList);
				break;
			case RowStateConstant.UPDATE:
				vo.setAttrId(attrId);
				updateList.add(vo);
				validValue(attrId, vo, existValueList);
				break;
			case RowStateConstant.DELETE:
				deleteList.add(vo.getId().toString());
				break;
			default:
				break;
			}
		}

		if (existValueList.size() > 0) {
			throw new CrmBusinessException("【"+StringUtils.join(existValueList, ",")+"】属性值已存在，保存失败！");
		}
		
		batchInsertVO(attrId, addList);
		batchUpdateVO(updateList);
		batchDeleteVO(attrId, deleteList);
	}
	
	/**
	 * 批量删除
	 * @param attrIds
	 */
	public void batchDeleteVO(String[] attrIds) {
		
		Map<String, Object> paraMap = new HashMap<String, Object>();
		paraMap.put("deletedUserId", new Long(InvocationInfoProxy.getParameter("id")));
		paraMap.put("deletedTime", new Date());
		paraMap.put("attrIds", attrIds);
		
		dao.updateSql(AttrBVO.class, "batchDeleteAttrBByAttrId", paraMap);
	}
	
	/**
	 * 获得被属性组引用的属性值
	 * @param attrId
	 * @param valueList
	 * @return
	 */
	public List<String> getAttrGroupRefValueList(Long attrId, List<String> valueList) {
		Map<String, Object> paraMap = new HashMap<String, Object>();
		paraMap.put("attrId", attrId);
		paraMap.put("values", valueList);
		return dao.selectStrList(AttrBVO.class, "getAttrGroupRefValueList", paraMap);
	}
	
	/**
	 * 属性值是否存在
	 * @param attrId
	 * @param id
	 * @param value
	 * @return
	 */
	public int getCountByValue(Long attrId, Long id, String value) {
		Map<String, Object> paraMap = new HashMap<String, Object>();
		paraMap.put("attrId", attrId);
		paraMap.put("id", id);
		paraMap.put("value", value);
		paraMap.put("tenantId", InvocationInfoProxy.getTenantid());
		return dao.countAll(AttrBVO.class, "getCountByValue", paraMap);
	}
	
	/**
	 * 获取属性值参照列表
	 * @param attrId
	 * @return
	 */
	public List<AttrBVO> getRefList(Long attrId) {
		Map<String, Object> paraMap = new HashMap<String, Object>();
		paraMap.put("attrId", attrId);
		return dao.selectVoList(AttrBVO.class, "getRefList", paraMap);
	}
	
	/**
	 * 是否被属性组引用
	 * @param attrGroupId
	 * @return
	 */
	public boolean isCitedByAttrGroup(Long valueId) {
		return dao.countAll(AttrBVO.class, "getAGCountByValueId", valueId) > 0;
	}
	
	/**
	 * 根据属性id获得被属性组引用的属性值id
	 * @param attrId
	 * @return
	 */
	public List<String> getIdsByAttrGroup(Long attrId) {
		return dao.selectStrList(AttrBVO.class, "getValueIdsByAttrIdFromAR", attrId);
	}
	
	private void batchUpdateVO(List<AttrBVO> voList) {
		
		if (voList == null || voList.size() == 0) {
			return;
		}
		
		Date date = new Date();
		Long userId = new Long(InvocationInfoProxy.getParameter("id"));
		
		for (AttrBVO vo : voList) {

			vo.setSysModifiedTime(date);
			vo.setSysModifiedUserId(userId);
			vo.setEnableTime(date);
			vo.setEnableUserId(userId);
		}

		dao.updateSql(AttrBVO.class, "batchUpdateAttrB", voList);
	}

	private void batchDeleteVO(Long attrId, List<String> idList) {
		
		if (idList == null || idList.size() == 0) {
			return;
		}
		
		List<String> uRefValueList = getAttrGroupRefValueList(attrId, idList);
		
		if (uRefValueList.size() > 0) {
			throw new CrmBusinessException("【"+StringUtils.join(uRefValueList, ",")+"】属性值被属性组引用，保存失败！");
		}
				
		dao.batchDelete(AttrBVO.class, idList);
	}
	
	/**
	 * 校验属性值是否存在
	 * @param attrId
	 * @param vo
	 * @param existValueList
	 */
	private void validValue(Long attrId, AttrBVO vo, List<String> existValueList) {

		if (vo.getId() != null && vo.getId() == 0) {
			vo.setId(null);
		}
		
		int count = getCountByValue(attrId, vo.getId(), vo.getValue());
		if (count > 0) {
			existValueList.add(vo.getValue());
		}
	}
}
